package com.micro.ai.models.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.models.entity.FineTuningDataset;
import com.micro.ai.models.mapper.FineTuningDatasetMapper;
import com.micro.ai.models.service.FineTuningDatasetService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 微调数据集服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class FineTuningDatasetServiceImpl extends ServiceImpl<FineTuningDatasetMapper, FineTuningDataset> implements FineTuningDatasetService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FineTuningDataset create(FineTuningDataset dataset) {
        if (dataset == null) {
            throw new BusinessException("M0000", "数据集信息不能为空");
        }
        
        LocalDateTime now = LocalDateTime.now();
        dataset.setCreatedAt(now);
        dataset.setUpdatedAt(now);
        if (dataset.getStatus() == null) {
            dataset.setStatus("uploading");
        }
        
        boolean success = this.save(dataset);
        if (!success) {
            throw new BusinessException("M0003", "保存数据集失败");
        }
        
        log.info("创建数据集成功: datasetId={}, name={}", dataset.getId(), dataset.getName());
        return dataset;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FineTuningDataset update(String id, FineTuningDataset dataset) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "数据集ID不能为空");
        }
        if (dataset == null) {
            throw new BusinessException("M0000", "数据集信息不能为空");
        }
        
        FineTuningDataset existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("M0002", "数据集不存在: " + id);
        }
        
        dataset.setId(id);
        dataset.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(dataset);
        if (!success) {
            throw new BusinessException("M0003", "更新数据集失败");
        }
        
        log.info("更新数据集成功: datasetId={}", id);
        return dataset;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "数据集ID不能为空");
        }
        
        FineTuningDataset dataset = this.getById(id);
        if (dataset == null) {
            throw new BusinessException("M0002", "数据集不存在: " + id);
        }
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("M0003", "删除数据集失败");
        }
        
        log.info("删除数据集成功: datasetId={}, name={}", id, dataset.getName());
    }

    @Override
    public Page<FineTuningDataset> pageQuery(int pageNum, int pageSize, String tenantId, String keyword, String status) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 20;
        }
        
        Page<FineTuningDataset> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<FineTuningDataset> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(FineTuningDataset::getTenantId, tenantId);
        }
        if (StringUtils.hasText(status)) {
            query.eq(FineTuningDataset::getStatus, status);
        }
        if (StringUtils.hasText(keyword)) {
            query.and(q -> q.like(FineTuningDataset::getName, keyword)
                          .or().like(FineTuningDataset::getDescription, keyword));
        }
        
        query.orderByDesc(FineTuningDataset::getCreatedAt);
        
        return this.page(page, query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void process(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("M0000", "数据集ID不能为空");
        }
        
        FineTuningDataset dataset = this.getById(id);
        if (dataset == null) {
            throw new BusinessException("M0002", "数据集不存在: " + id);
        }
        
        dataset.setStatus("processing");
        dataset.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(dataset);
        if (!success) {
            throw new BusinessException("M0003", "更新数据集状态失败");
        }
        
        log.info("开始处理数据集: datasetId={}, name={}", id, dataset.getName());
        
        // 异步处理数据集（避免阻塞主线程）
        processDatasetAsync(dataset);
    }
    
    @Autowired(required = false)
    private FineTuningDatasetProcessor datasetProcessor;
    
    @Autowired
    private com.micro.ai.models.service.DatasetRecordService datasetRecordService;
    
    /**
     * 异步处理数据集
     * 注意：实际实现需要根据业务需求选择处理方式
     * 1. 使用@Async注解异步执行
     * 2. 或使用消息队列（RabbitMQ、Kafka等）
     * 3. 或使用线程池执行
     */
    private void processDatasetAsync(FineTuningDataset dataset) {
        // 方案1: 使用Spring @Async（需要配置异步支持）
        // 方案2: 使用消息队列
        // 方案3: 使用线程池
        
        // 这里提供基础框架，实际处理逻辑需要根据业务需求实现
        
        if (datasetProcessor != null && dataset.getFilePath() != null) {
            try {
                // 解析数据集文件
                List<FineTuningDatasetProcessor.DatasetRecordParseResult> records = 
                    datasetProcessor.parseDatasetFile(dataset.getFilePath(), dataset.getFileFormat());
                
                // 计算质量评分
                double qualityScore = datasetProcessor.calculateDatasetQualityScore(records);
                
                // 更新数据集信息
                dataset.setTotalRecords(records.size());
                dataset.setQualityScore(qualityScore);
                dataset.setStatus("ready");
                dataset.setUpdatedAt(LocalDateTime.now());
                this.updateById(dataset);
                
                // 保存数据记录到 dataset_records 表
                saveDatasetRecords(dataset.getId(), dataset.getTenantId(), records);
                
                log.info("数据集处理完成: datasetId={}, records={}, qualityScore={}", 
                        dataset.getId(), records.size(), qualityScore);
                
            } catch (Exception e) {
                log.error("处理数据集失败: datasetId={}, error={}", dataset.getId(), e.getMessage(), e);
                dataset.setStatus("error");
                dataset.setErrorMessage("处理失败: " + e.getMessage());
                this.updateById(dataset);
            }
        } else {
            log.warn("数据集处理器未配置或文件路径为空，跳过实际处理: datasetId={}", dataset.getId());
            // 如果不需要实际处理，直接设置为ready状态
            dataset.setStatus("ready");
            dataset.setUpdatedAt(LocalDateTime.now());
            this.updateById(dataset);
        }
    }
    
    /**
     * 批量保存数据集记录
     */
    private void saveDatasetRecords(String datasetId, String tenantId, 
                                   List<FineTuningDatasetProcessor.DatasetRecordParseResult> parseResults) {
        List<com.micro.ai.models.entity.DatasetRecord> records = new ArrayList<>();
        
        for (FineTuningDatasetProcessor.DatasetRecordParseResult result : parseResults) {
            com.micro.ai.models.entity.DatasetRecord record = new com.micro.ai.models.entity.DatasetRecord();
            record.setDatasetId(datasetId);
            record.setTenantId(tenantId);
            record.setRecordIndex(result.getRecordIndex());
            record.setInputText(result.getInputText());
            record.setOutputText(result.getOutputText());
            record.setInstruction(result.getInstruction());
            record.setQualityScore(result.getQualityScore());
            record.setIsValid(result.getIsValid() != null && result.getIsValid());
            record.setCreatedAt(LocalDateTime.now());
            
            records.add(record);
        }
        
        // 批量保存（每批1000条）
        int batchSize = 1000;
        for (int i = 0; i < records.size(); i += batchSize) {
            int end = Math.min(i + batchSize, records.size());
            List<com.micro.ai.models.entity.DatasetRecord> batch = records.subList(i, end);
            datasetRecordService.saveBatch(batch);
        }
        
        log.info("保存数据集记录完成: datasetId={}, count={}", datasetId, records.size());
    }
}

